import moment from 'moment';
import Message from './message';
import AgentService, { IOperationName, IOperationType } from '@/modules/Agent';
import i18next from './i18next/i18n';
const { t } = i18next;
import {
	initErrorResponse,
	loginErrorResponse,
	onDropErrorResponse,
	readyErrorResponse,
	unReadyErrorResponse,
	appointErrorResponse,
	checkInErrorResponse,
	checkOutErrorResponse,
	answerErrorResponse,
	ccsErrorResponse,
	ConnectStatusErrorResponse,
	systemErrorResponse,
	transferErrorResponse
} from './errorResponse';
import store from '@/store';
import { IAudioConstraints, IVideoConstraints } from '@/modules/interface';
import { cancelInvitationsErrorResponse } from '@/modules/errorResponse';
import clog from '@/modules/CLog';


export interface StreamAdd {
	type: string;
	data: StreamAddData;
}

interface StreamAddData {
	audioOnly: boolean;
	id: string;
	videoId: string;
	streamLabel: string;
	userInfo: {
		clientId: string;
		customerRole: string;
		userName: string;
		from: any;
	};
}

export interface StreamEnd {
	type: string;
	data: StreamEndData;
}

interface StreamEndData {
	streamLabel: string;
	userInfo?: {
		clientId?: string;
		customerRole?: string;
		userName?: string;
		from?: any;
	};
}

export interface AnswerProps {
	sessionData: SessionDataProps;
	publicationId: string;

	[propsName: string]: any;
}

export interface SessionDataProps {
	clientId: string;
	roomId: string;
	recordingId: string;
	members?: any[];
	[propsName: string]: any;
}

export interface IMediaDevices {
	audioConstraints: IAudioConstraints;
	videoConstraints: IVideoConstraints;
	publishOptions: any;
}

let streamAddEvent: EventListener | null = null;
let streamEndEvent: EventListener | null = null;
let ccsErrorEvent: EventListener | null = null;
let customerQuitEvent: EventListener | null = null;
let customerJoinEvent: EventListener | null = null;
let agentQuitEvent: EventListener | null = null;
let agentJoinSessionEvent: EventListener | null = null;
let systemErrorEvent: EventListener | null = null;

interface InitDataProps {
	backendUrl?: string;
	groupsList?: [];
	rtmpServer?: string;
	token?: string;
}

//初始化
const initWithEncrypt = (username: string, password: string, org: string | number): Promise<InitDataProps> => {
	return new Promise((resolve, reject) => {
        ivcs.agent.setcompressedPublicKey(AgentService.configure.getPublicKey());
		ivcs.agent.initWithEncrypt(
			AgentService.configure.serviceUrl,
			username,
			password,
			org,
			undefined,
			AgentService.configure.defaultMediaOptions,
			resp => {
				console.log('init success', resp);
				localStorage.setItem('agent-widget-token', resp.token);
				const length = resp.groupsList.length;
				if (length === 0) {
					Message.warning(t('no-group-contact-admin'));
				} else {
					resolve(resp);
				}
			},
			error => {
				console.log('init error', error);
				initErrorResponse(error.code);
				reject(error);
			}
		);
	});
};

//登入
const loginSystem = (): Promise<{ code: number; data: { agentId: string; refersh_ticket_time: number; ticket: string } }> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.login(
			data => {
				console.log('login success', data);
				resolve({ code: 200, data });
			},
			error => {
				console.log('login error', error);
				loginErrorResponse(error.code);
				reject(error);
			}
		);
	});
};

//振铃
const onRing = (callBack: (data: any) => void) => {
	ivcs.agent.onRing(data => {
		console.log(data, 'onRing');
		sessionStorage.setItem('sessionId', data.sessionId);
		callBack(data);
	});
};

//取消振铃
const onCancelRing = (callBack: (reason: undefined | string) => void) => {
	ivcs.agent.onCancelRing(reason => {
		sessionStorage.setItem('sessionId', '');
		console.log('stop ring,', reason);
		callBack(reason);
	});
};

//连接异常，被系统强制结束或者其他网络原因，触发后坐席端无法正常处理会话，需要重新初始化
const onDrop = (callback: (code: string | number) => void) => {
	ivcs.agent.onDrop(resp => {
		console.log('on drop resp,', resp);
		onDropErrorResponse(resp.code);
		callback && callback(resp.code);
	});
};

//遍历分组
const cacheGroupList = (groups: any) => {
	let groupsList: { name: string; id: number }[] = [];
	groups.forEach((item: any) => {
		groupsList.push({
			name: item.name,
			id: item._id
		});
	});
	return groupsList;
};

const getCustomerInfo = (info: any) => {
	let userInfo = {};
	if (info.user && info.user.profile) {
		userInfo = {
			id: info.user.id,
			org: info.user.org,
			gender: info.user.profile.gender,
			fullName: info.user.profile.fullName,
			avatar: info.user.profile.picture,
			userName: info.user.name,
			role: info.role,
			customerLevel: info.user.customerLevel,
			clientId: info.id
		};
	}
	return userInfo;
};

//就绪
const ready = () => {
	return new Promise((resolve, reject) => {
		ivcs.agent.ready(
			resp => {
				console.log('ready success', resp);
				resolve({ code: 200, message: 'ready success' });
			},
			error => {
				console.log('ready error', error);
				readyErrorResponse(error.code);
				reject(error);
			}
		);
	});
};

//取消就绪
const unReady = () => {
	return new Promise((resolve, reject) => {
		ivcs.agent.unReady(
			resp => {
				console.log('unReady success', resp);
				resolve({ code: 200, message: 'unReady success' });
			},
			error => {
				console.log('unReady error', error);
				unReadyErrorResponse(error.code);
				reject(error);
			}
		);
	});
};

//预约小休
const appoint = (data: { reason: string }) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.appoint(
			data,
			resp => {
				console.log('appoint success', resp);
				resolve({ code: 200, message: 'appoint success' });
				Message.normal(t('break-book-success'));
			},
			error => {
				console.log('appoint error', error);
				Message.warning(t('break-book-failed'));
				reject(error);
			}
		);
	});
};

//小休
const setOtherWork = (data: { reason: string }) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.otherWork(
			data,
			resp => {
				console.log('setOtherWork success', resp);
				resolve({ code: 200, message: 'appoint success' });
			},
			error => {
				console.log('setOtherWork error', error);
				appointErrorResponse(error.code);
				reject(error);
			}
		);
	});
};

//设置小休原因
const setOtherWorkReason = (data: { reason: string }) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.setOtherWorkReason(
			data,
			resp => {
				console.log('setOtherWorkReason success', resp);
				resolve({ code: 200, message: 'appoint success' });
			},
			error => {
				console.log('setOtherWorkReason error', error);
				appointErrorResponse(error.code);
				reject(error);
			}
		);
	});
};

//签入分组
const checkIn = (checkInGroups: { groups: number[] }) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.checkIn(
			checkInGroups,
			(resp: any) => {
				console.log('checkin success', resp);
				getQueueInfo();
				let timer = window.setInterval(() => {
					getQueueInfo();
				}, 2000);
				AgentService.setCallProgressTimer(timer);
				resolve({ code: 200, message: 'checkin success' });
			},
			(error: any) => {
				console.log('checkin error', error);
				checkInErrorResponse(error.code);
				reject(error);
			}
		);
	});
};

//签出分组
const checkOut = (checkInGroups: { groups: number[] }) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.checkOut(
			checkInGroups,
			(resp: any) => {
				console.log('checkout success', resp);
				AgentService.removeCallProgressTimer();
				resolve({ code: 200, message: 'checkout success' });
			},
			(error: any) => {
				console.log('checkout error', error);
				checkOutErrorResponse(error.code);
				reject(error);
			}
		);
	});
};

const joinSession = (agentLabel: string, sessionId: string, bizScenarioId: string): Promise<AnswerProps> => {
	const token = AgentService.token;
	return new Promise((resolve, reject) => {
		ivcs.agent.joinSession(
			agentLabel,
			undefined,
			token,
			AgentService.configure.serviceUrl,
			sessionId,
			bizScenarioId,
			(resp: any) => {
				console.log('joinSession', resp);
				AgentService.setUser({ clientId: resp.sessionData.clientId });
				businessInit();
				resolve(resp);
			},
			(error: any) => {
				//  失败'5008':会话已结束,5012':会话正在业务场景转接中，无法加入》 其他错误参考错误码
				console.log('joinSession error', error);
				if (error.code === '5008') {
					Message.warning(t('can-not-join-session-closed'));
				} else if (error.code === '5012') {
					Message.warning(t('can-not-join-session-transfering'));
				}
				reject(error);
			},
			(joinSession: any) => {
				console.log('joinSession success', joinSession);
				AgentService.setSessionMembers(joinSession.sessionData.members);
				AgentService.setIsAutoSystemRecord(joinSession.sessionData.isAutoSystemRecord);
			}
		);
	});
};

const joinSessionWithSessionId = (sessionId: string, bizScenarioId: string): Promise<AnswerProps> => {
	return new Promise((resolve, reject) => {
		ivcs.agent.joinSession(
			sessionId,
			bizScenarioId,
			(resp: any) => {
				console.log('joinSession', resp);
				AgentService.setUser({ clientId: resp.sessionData.clientId });
				businessInit();
				resolve(resp);
			},
			(error: any) => {
				//  失败'5008':会话已结束,5012':会话正在业务场景转接中，无法加入》 其他错误参考错误码
				console.log('joinSession error', error);
				if (error.code === '5008') {
					Message.warning(t('can-not-join-session-closed'));
				} else if (error.code === '5012') {
					Message.warning(t('can-not-join-session-transfering'));
				}
				reject(error);
			},
			(joinSession: any) => {
				console.log('joinSession success', joinSession);
				AgentService.setSessionMembers(joinSession.sessionData.members);
				AgentService.setIsAutoSystemRecord(joinSession.sessionData.isAutoSystemRecord);
			}
		);
	});
};

//接听呼叫
const answer = (agentName: string, receiveMediaType: string, customizedMediaStream: any, mediaDevices: IMediaDevices): Promise<AnswerProps> => {
	let agentLabel = 'agent' + agentName + '-' + Math.round(Math.random() * (1 - 10000) + 10000);
	return new Promise((resolve, reject) => {
		ivcs.agent.answer(
			agentLabel,
			receiveMediaType,
			customizedMediaStream,
			mediaDevices,
			resp => {
				console.log('answer result,', resp);
				AgentService.setUser({ clientId: resp.sessionData.clientId });
				resp.sessionData.members.forEach((item: { role: string }) => {
					if (item.role === 'customer') {
						let user = getCustomerInfo(item);
						sessionStorage.setItem('customer', JSON.stringify(user));
					}
				});
				businessInit();
				resolve(resp);
			},
			error => {
				console.log('answer call error', error);
				answerErrorResponse(error.code);
				reject(error);
			}
		);
	});
};

//拒绝
const rejectSession = () => {
	return new Promise((resolve, reject) => {
		ivcs.agent.reject(
			resp => {
				resolve(resp);
			},
			error => {
				reject(error);
			}
		);
	});
};

//监听流加入
const onStreamAdd = (callBack: (streamInfo: StreamAdd) => void) => {
	streamAddEvent = ivcs.agent.addEventListener('onStreamAdd', streamInfo => {
		console.log('add steam attributes', streamInfo);
		callBack(streamInfo);
	});
};

//监听流退出
const onStreamEnd = (callBack: (streamInfo: StreamEnd) => void) => {
	streamEndEvent = ivcs.agent.addEventListener('onStreamEnd', streamInfo => {
		callBack(streamInfo);
	});
};

//渲染视频流
const renderStream = (streamLabel: string, videoId: string, callBack?: (onEnded: any) => void, subscribeSuccess?: (stream: MediaStream) => void) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.renderStream(
			streamLabel,
			videoId,
			resp => {
				console.log('render success', resp, videoId, streamLabel);
				resolve({ status: 'success', message: resp });
			},
			error => {
				console.log('render error', error);
				reject({ status: 'error', message: error });
			},
			onPlayError => {
				console.log('onPlayError error', onPlayError);
				reject({ status: 'onPlayError', message: onPlayError });
			},
			onEnded => {
				console.log('onEnded error', onEnded);
				callBack && callBack(onEnded);
				reject({ status: 'onEnded', message: onEnded });
			},
			(stream: MediaStream) => {
				console.log('subscribeSuccess:', stream);
				subscribeSuccess && subscribeSuccess(stream);
			}
		);
	});
};

//挂断
const hangup = () => {
	return new Promise((resolve, reject) => {
		let hangUpReason = {};
		ivcs.agent.hangup(
			hangUpReason,
			resp => {
				removeSessionListenerEvent();
				resolve({ code: 200 });
			},
			error => {
				reject(error);
			}
		);
	});
};

//监听访客加入会话
const onCustomerJoinSession = (callBack: (info: any) => void) => {
	customerJoinEvent = ivcs.agent.addEventListener('onCustomerJoinSession', info => {
		const client = t('client');
		const join = t('join-session');
		Message.normal(`${client}<${info.data.user.name}>${join}`);
		callBack(info);
	});
};

//监听访客离开会话
const onCustomerQuitSession = (callBack: (info: any) => void) => {
	customerQuitEvent = ivcs.agent.addEventListener('onCustomerQuitSession', info => {
		const client = t('client');
		const leave = t('leave-session');
		Message.normal(`${client}<${info.data.user.name}>${leave}`);
		callBack(info);
	});
};

//监听坐席离开会话
const onAgentQuitSession = (callBack: (info: any) => void) => {
	agentQuitEvent = ivcs.agent.addEventListener('onAgentQuitSession', info => {
		const agent = t('agent');
		const leave = t('leave-session');
		Message.normal(`${agent}<${info.data.user.name}>${leave}`);
		callBack(info);
	});
};

//监听坐席加入会话
const onAgentJoinSession = (callBack: (info: any) => void) => {
	agentJoinSessionEvent = ivcs.agent.addEventListener('onAgentJoinSession', info => {
		const agent = t('agent');
		const joined = t('joined-session');
		Message.normal(`${agent}<${info.data.user.name}>${joined}`);
		callBack(info);
	});
};

//监听ccs结束会话
const onCcsDrop = (callBack: (resp: { code: number; message: string }) => void) => {
	ivcs.agent.onSessionDrop(resp => {
		Message.warning(t('force-end-session'));
		callBack(resp);
	});
};

//cssError
const ccsError = (callBack: (error: any) => void) => {
	ccsErrorEvent = ivcs.agent.addEventListener('ccsError', error => {
		if (error.data && error.data.code) {
			ccsErrorResponse(error.data.code);
		}
		callBack(error);
	});
};

const systemError = (callBack: (error: any) => void) => {
	systemErrorEvent = ivcs.agent.addEventListener('systemError', error => {
		// ivcs.agent.onConnectStatus(status => {
		// 	console.log('onConnectStatus', status);
		// 	ConnectStatusErrorResponse(status);
		// });
		console.log('system error', error, error.data.data, error.code);
		systemErrorResponse(error.code, error.data);
		callBack(error);
	});
};

//移除事件监听
const removeSessionListenerEvent = () => {
	ivcs.agent.removeEventListener('onStreamAdd', streamAddEvent!);
	ivcs.agent.removeEventListener('onStreamEnd', streamEndEvent!);
	ivcs.agent.removeEventListener('onCustomerQuitSession', customerQuitEvent!);
	ivcs.agent.removeEventListener('onAgentQuitSession', agentQuitEvent!);
	ivcs.agent.removeEventListener('onAgentJoinSession', agentJoinSessionEvent!);
	ivcs.agent.removeEventListener('ccsError', ccsErrorEvent!);
	ivcs.agent.removeEventListener('systemError', systemErrorEvent!);
	streamAddEvent = null;
	streamEndEvent = null;
	customerQuitEvent = null;
	agentQuitEvent = null;
	agentJoinSessionEvent = null;
	ccsErrorEvent = null;
	systemErrorEvent = null;
};

const businessInit = () => {
	onScreenShot();
};

//截屏
const screenshot = (clientId: string) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.screenshot(
			undefined,
			clientId,
			resp => {
				resolve(resp);
			},
			error => {
				reject(error);
				Message.error(error);
			}
		);
	});
};

const onScreenShot = () => {
	ivcs.agent.onScreenShot(data => {
		if (data.data.status === 'done') {
			console.log(data, 'screenshot result');
		}
	});
};

//转接
const transfer = (option: any, transferReason: { reason: string }) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.transfer(
			option,
			true,
			transferReason,
			resp => {
				Message.normal(t('success'));
				console.log('transfer:', resp);

				resolve(resp);
			},
			error => {
				transferErrorResponse(error, 'transfer', option);
				reject(error);
			}
		);
	});
};

const transferBizscenario = (option: any) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.transferBizscenario(
			option,
			(resp: any) => {
				Message.normal(t('success'));
				console.log('transfer:', resp);
				resolve(resp);
			},
			(error: any) => {
				transferErrorResponse(error, 'transfer', option);
				reject(error);
			}
		);
	});
};

//三方
const inviteOther = (option: any) => {
	ivcs.agent.inviteOther(
		option,
		(resp: any) => {
			if (resp.waitingCode && resp.waitingCode !== '-1') {
				Message.error(resp.message);
			} else {
				Message.normal(t('success'));
			}
		},
		(error: any) => {
			console.log(error, 'inviteOther error');
			transferErrorResponse(error, 'invite', option);
		},
		(progress: any) => {}
	);
};

// 静音, 取消静音
type Mute = 'mute' | 'unmute';
type Source = 'audio' | 'video';
const muteStream = (mode: Mute, source: Source, videoId: string) => {
	return new Promise((resolve, reject) => {
		ivcs.agent[mode](
			source,
			success => {
				muteLocalStream(mode, source, videoId);
				resolve(success);
			},
			error => {
				reject(error);
			}
		);
	});
};

const muteLocalStream = (mode: Mute, source: Source, videoId: string) => {
	let video = document.getElementById(`${videoId}`) as HTMLVideoElement;
	if (source === 'video') {
		mode === 'mute' ? video.pause() : video.play();
	} else {
		video!.muted = mode === 'mute' ? true : false;
	}
	console.log('muteLocalStream:', video.muted, video.paused);
};

// 语音升级视频
const voiceToVideo = (customStream = undefined, videoId: string | undefined, videoInputDeviceId?: string | undefined) => {
	let audioDeviceID = AgentService.getAudioDeviceID() ? AgentService.getAudioDeviceID() : AgentService.getDefaultAudioInputDeviceID();
	let videoDeviceID = videoInputDeviceId ? videoInputDeviceId : AgentService.getVideoDeviceID();
	return new Promise((resolve, reject) => {
		ivcs.agent.voiceToVideo(
			success => {
				resolve(success);
			},
			error => {
				reject(error);
			},
			customStream,
			videoId,
			audioDeviceID,
			videoDeviceID
		);
	});
};

// 视频降级语音
const videoToVoice = (audioInputDeviceID?: string | undefined) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.videoToVoice(
			success => {
				resolve(success);
			},
			error => {
				reject(error);
			},
			audioInputDeviceID
		);
	});
};

// 发送自定义消息
const sendCustomeizeMessage = (data: string | object = {}, toRole: string) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.sendCustomMessage(
			data,
			toRole,
			success => {
				resolve(success);
			},
			error => {
				reject(error);
			}
		);
	});
};

// 接收自定义消息
const receiveCustomizeMessage = (callback: (message: any) => void) => {
	ivcs.agent.onCustomMessage(data => {
		console.log('onCustommessage:', data);
		callback(data);
	});
};

// 接受文本消息
const onTextMessage = (callback: (message: any) => void) => {
	ivcs.agent.onTextMessage(data => {
		callback(data);
	});
};
// 屏幕共享
const agentScreenShare = (role = 'all') => {
	return new Promise((resolve, reject) => {
		ivcs.agent.screenShare(
			success => {
				resolve(success);
			},
			error => {
				reject(error);
			},
			stop => {
				resolve(stop);
			},
			AgentService.user?.userName || '',
			role
		);
	});
};

// 结束屏幕共享
const stopScreenShare = (publicationId: string) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.stopScreenShare(
			publicationId,
			success => {
				resolve(success);
			},
			error => {
				reject(error);
			}
		);
	});
};

// 开启屏幕标注
const screenMark = (role = 'customers') => {
	return new Promise((resolve, reject) => {
		ivcs.agent.screenMark(
			undefined,
			role,
			success => {
				resolve(success);
			},
			error => {
				reject(error);
			}
		);
	});
};

// 取消标注
const stopScreenMark = (role = 'customers') => {
	return new Promise((resolve, reject) => {
		ivcs.agent.cancelScreenMark(
			'',
			role,
			success => {
				resolve(success);
			},
			error => {
				reject(error);
			}
		);
	});
};

//根据文件详情发送文件资源<主要用于IM里面发送文件图片等>
const shareResourceWithFileInfo = (type: string, data: any, role: string) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.shareResourceWithFileInfo(
			type,
			data,
			role,
			resp => resolve(resp),
			error => reject(error)
		);
	});
};

//收到资源文件信息（图片，文档等）
const onResourceMessage = (callback: (data: any) => void) => {
	ivcs.agent.onResourceMessage(data => {
		callback(data);
	});
};

//保存人脸识别后的结果
const saveFaceRecognition = (result: any, clientId: string) => {
	ivcs.agent.faceRecognition(
		result,
		clientId,
		resp => {
			console.log(resp, 'faceRecognition');
		},
		error => {
			console.log(error, 'faceRecognition');
		}
	);
};

//保存人证识别后的结果
const saveCardRecognition = (result: any, clientId: string) => {
	ivcs.agent.faceIdcardValidate(
		result,
		clientId,
		resp => {
			console.log(resp, 'faceIdcardValidate success');
		},
		error => {
			console.log(error, 'faceIdcardValidate error');
		}
	);
};

// 发送文本消息
const sendTextMessage = (message: string) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.sendTextMessage(
			message,
			'others',
			resp => {
				console.log(message, '返回数据');
				resolve(resp);
			},
			error => {
				console.log('send text message error', error);
				reject(error);
				Message.error(t('send-message-failed'));
				clog.error(error.code as number, error);
			}
		);
	});
};

// 切换视频流
const switchCameraWithStream = (stream: MediaStream) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.switchCameraWithStream(
			stream,
			resp => {
				console.log('switch camera success', resp, stream);
				resolve({ status: 'success', message: resp });
			},
			error => {
				console.log('switch camera error', error);
				reject({ status: 'error', message: error });
			},
			onEnded => {
				console.log('switch camera onEnded', onEnded);
				reject({ status: 'onEnded', message: onEnded });
			}
		);
	});
};

/**
 * 监听访客端本地推送画面的媒体连接状态。
 * @param {function} ack {streamLabel:string(本地推流标签),userInfo:object(该画面包含的client信息),publishStatus:{status:string('failed'|'connecting'|'connected'|'disconnected'|'quality-report'),data:object(网络状况信息)}}
 * @example
 * ivcs.agent.onPublishMediaStatus((info)=>{});
 */
const onPublishMediaStatus = (callBack: (resp: { streamLabel: string; publishStatus: { status: string }; data: Object; userInfo: Object }) => void) => {
	ivcs.agent.onPublishMediaStatus((resp: any) => {
		// store dispatch
		callBack(resp);
	});
};

/**
 * 监听渲染的远端画面的媒体连接状态。
 * @param {function} ack {streamLabel:string(渲染的流标签),userInfo:object(该画面包含的client信息),renderStatus:{status:string('failed'|'connecting'|'connected'|'disconnected'|'quality-report'),data:object(网络状况信息)}}
 * @example
 * ivcs.agent.onRenderMediaStatus((info)=>{});
 */
const onRenderMediaStatus = (callBack: (resp: { streamLabel: string; renderStatus: { status: string }; data: Object; userInfo: Object }) => void) => {
	ivcs.agent.onRenderMediaStatus((resp: any) => {
		// store dispatch
		callBack(resp);
	});
};

/**
 * 监听坐席和坐席管理服务端<ams>的链接的状态变化
 * @param {function} ack 返回{enum:['connected','reconnect_failed','reconnecting']}
 * @example
 * ivcs.agent.onConnectStatus(status => {
        //开发者的业务处理示例
        'connected':'链接成功/重连成功',//第一次触发表示和ams建立链接,后面触发表示重连成功
        'reconnect_failed':'重连失败',//无法接听，就绪，签入等任何功能,需要重新初始化
        'reconnecting':'正在重连中...'//正在重连中，无法执行任何操作
        'offline':'断网',
        'online':'网络恢复链接'
    });
*/
const onAmsConnectStatus = (callBack: (status: string) => void) => {
	ivcs.agent.onConnectStatus((status: string) => {
		console.log('onConnectStatus', status);
		callBack(status);
	});
};

/**
 * 监听session中其他用户ccs重连中,用于检测对方网络是否断开在重连中
 * @param {function} ack
 * @returns null
 */
const onOtherReconnecting = (callBack: (ack: any) => void) => {
	ivcs.agent.onOtherReconnecting((ack: any) => {
		console.log('onOtherReconnecting', ack);
		callBack(ack);
	});
};

/**
 * 监听session中其他用户ccs重连成功,用于检测对方网络是否重连成功
 * @param {function} ack
 * @returns null
 */
const onOtherResumeConnect = (callBack: (ack: any) => void) => {
	ivcs.agent.onOtherResumeConnect((ack: any) => {
		console.log('onOtherResumeConnect', ack);
		callBack(ack);
	});
};

/**
 * 监听坐席和Ccs会话状态变化
 * @param {function} ack 返回{enum:['connected','reconnect_failed','reconnecting']}
 * @example
 */

const onSessionConnectStatus = (callBack: (ack: any) => void) => {
	ivcs.agent.onSessionConnectStatus((ack: any) => {
		console.log('onSessionConnectStatus', ack);
		callBack(ack);
	});
};

/**
 * 坐席免登录页面,根据登录api接口返回的数据进行初始化
 * @param {string} backendUrl 请求的后台服务地址
 * @param {object} data 登录接口返回的response.data数据。
 */
const initWithLoginData = (backendUrl: string, data: any) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.initWithLoginData(
			backendUrl,
			data,
			undefined,
			(resp: any) => {
				console.log(resp, '返回数据');
				resolve(resp);
			},
			(error: any) => {
				console.log('init with login data error', error);
				reject(error);
			}
		);
	});
};

//获取排队数
const getQueueInfo = () => {
	let num = 0;
	ivcs.agent.getQueueInfo(
		(resp: any) => {
			// console.log('get queue info success', resp);
			AgentService.setCallProgressGroups(
				resp.map((item: any) => {
					return {
						scenName: item.bizscenario.name,
						scenId: item.scenId,
						groupId: item.groupId,
						waitingNum: item.waitingNum
					};
				})
			);
			resp.forEach((item: any) => {
				num = num + Number(item.waitingNum);
			});
			AgentService.updateCallProgress(num > 99999 ? 99999 : num);
		},
		(error: any) => {
			console.log('get queue info error', error);
		}
	);
};

//取消所有的invite（取消转接和三方）
const cancelInvitations = () => {
	return new Promise((resolve, reject) => {
		ivcs.agent.cancelInvitations(
			(resp: any) => {
				resolve(resp);
			},
			(error: any) => {
				reject(error);
				cancelInvitationsErrorResponse(error.code);
			}
		);
	});
};

const onInvitationProgress = (callBack: (ack: any) => void) => {
	ivcs.agent.onInvitationProgress((ack: any) => {
		callBack(ack);
	});
};

const onVariableChange = (callBack: (ack: any) => void) => {
	ivcs.agent.onVariableChange((ack: any) => {
		callBack(ack);
	});
};

// 开启系统录制
const startSystemRecord = () => {
	return new Promise((resolve, reject) => {
		ivcs.agent.startSystemRecord(
			(resp: any) => {
				resolve(resp);
			},
			(error: any) => {
				reject(error);
			}
		);
	});
};

// 停止系统录制
const stopSystemRecord = (recordId: string) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.stopSystemRecord(
			recordId,
			(success: any) => {
				resolve(success);
			},
			(error: any) => {
				reject(error);
			}
		);
	});
};

// 监听系统录像变化事件
const onSystemRecordUpdate = (callBack: (ack: any) => void) => {
	ivcs.agent.onSystemRecordUpdate((ack: any) => {
		callBack(ack);
	});
};

/** 屏幕水印 */
export const addScreenWatermark = (option: any) => {
	if (AgentService.user?.id && option) {
		let text = '';
		const userName = AgentService.user?.userName;
		const loginTime = localStorage.getItem('agent_login_time');
		if (option.content.includes('username')) {
			text = text + userName;
		}
		if (option.content.includes('loginTime') && loginTime) {
			const localDate = moment(Number(loginTime)).format('YYYY-MM-DD HH:mm:ss'); // 格式化时间戳
			text = text + ' ' + localDate;
		}
		option.txt = text;
	} else {
		option.txt = '';
	}

	option.alpha = option.alpha / 100;
	dstpSecurityPage.createWatermarking(option);
};

/** 去除屏幕水印 */
export const removeScreenWatermark = () => {
	dstpSecurityPage.createWatermarking({ txt: '' });
};

/**
 * 发送人工工作流节点完成情况
 * @param {object} message {humanflowId:(人工工作流ID),step:(人工工作流执行步骤ID),at:(时间)}
 * @param {string} toRole  发送给谁 string(clientId) = 会话中指定的用户 'customers' = 访客;'agents' = 坐席;'others' = 除了自己的所有人; 'all' = 所有人
 * @param {function} onSuccess 成功回调
 * @param {function} onFailure 失败回调
 * @example
 * ivcs.agent.sendHumanStepDetail(
						{humanflowId:1,// 人工工作流IDstep:11 // 人工工作流执行步骤IDat:"" // 时间}
						'agents',
						res => {
								console.log('sendHumanStepDetail success',res);
						},
						error => {
								console.log('sendHumanStepDetail error',error);
						}
				);
*/
export const sendHumanStepDetail = (message: {humanflowId: number, step: number}, toRole: string) => {
	return new Promise((resolve, reject) => {
		ivcs.agent.sendHumanStepDetail(
			{humanflowId: message.humanflowId, step: message.step, at: new Date().toISOString()},
			toRole,
			(success: any) => {
				resolve(success);
			},
			(error: any) => {
				reject(error);
			}
		);
	});
};

/**
 * 收到人工工作流节点完成情况
 * @param {function} ack  返回具体的节点完成数据  {humanflowId:(人工工作流ID),step:(人工工作流执行步骤ID),at:(时间)}
 * @example
 * ivcs.agent.onHumanStepDetail(data => {
			console.log('onHumanStepDetail data', data);
	});
*/
export const onHumanStepDetail = (callBack: (ack: any) => void) => {
	ivcs.agent.onHumanStepDetail((ack: any) => {
		callBack(ack);
	});
};

export {
	initWithEncrypt,
	loginSystem,
	onRing,
	onCancelRing,
	ready,
	unReady,
	appoint,
	setOtherWork,
	setOtherWorkReason,
	checkIn,
	checkOut,
	answer,
	onStreamAdd,
	renderStream,
	onStreamEnd,
	hangup,
	onCustomerQuitSession,
	onCustomerJoinSession,
	onAgentQuitSession,
	onAgentJoinSession,
	onCcsDrop,
	ccsError,
	systemError,
	muteStream,
	voiceToVideo,
	videoToVoice,
	screenshot,
	rejectSession,
	cacheGroupList,
	sendCustomeizeMessage,
	receiveCustomizeMessage,
	transfer,
	transferBizscenario,
	inviteOther,
	onTextMessage,
	agentScreenShare,
	screenMark,
	stopScreenShare,
	stopScreenMark,
	shareResourceWithFileInfo,
	onResourceMessage,
	saveFaceRecognition,
	onDrop,
	saveCardRecognition,
	sendTextMessage,
	joinSession,
	switchCameraWithStream,
	onPublishMediaStatus,
	onRenderMediaStatus,
	onAmsConnectStatus,
	onOtherReconnecting,
	onOtherResumeConnect,
	onSessionConnectStatus,
	initWithLoginData,
	getQueueInfo,
	cancelInvitations,
	onInvitationProgress,
	onVariableChange,
	startSystemRecord,
	stopSystemRecord,
	onSystemRecordUpdate,
	joinSessionWithSessionId
};
